#include <sdk.h>
#include <configurationpanel.h>
#include <wx/aui/auibook.h>
#include "XPMEditor.h"
#include "XPMColorPicker.h"

namespace {
  PluginRegistrant<XPMEditor> regMain( _T( "XPMEditor" ) );
}

XPMEditor* XPMEditor::m_Singleton = 0;

XPMEditor::XPMEditor() {
  if( !Manager::LoadResource( _T( "XPMEditor.zip" ) ) ) {
    NotifyMissingFile( _T( "XPMEditor.zip" ) );
  }
  ReadConfiguration( true );
}

XPMEditor::~XPMEditor() {
  if( m_Singleton == this ) {
    if( DefaultColourArray ) {
      delete[] DefaultColourArray;
    }
    m_Singleton = NULL;
  }
}

bool XPMEditor::CanHandleFile( const wxString& filename ) const {
  wxString fn;
  fn = filename;
  fn.MakeUpper();
  if( fn.Right( 4 ) == _( ".XPM" ) ) {
    if( iOpenXPM == 1 ) {
      return( false );
    }
    if( iOpenXPM == 2 ) {
      wxString sMsg;
      sMsg = _( "Do you want to open this file in the Image Editor ?" );
      sMsg += _( "\n" );
      sMsg += _( "If you click NO, then the file will be opened in the text editor" );
      if( ::wxMessageBox( sMsg, _( "Question" ), wxICON_QUESTION | wxYES_NO ) == wxID_NO ) {
        return( false );
      }
    }
    return( true );
  }
  if( fn.Right( 4 ) == _( ".ICO" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".CUR" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".XBM" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".BMP" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".TIF" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".JPG" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".JPE" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".DIB" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".PNG" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".PNM" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".PCX" ) ) {
    return( true );
  }
  if( fn.Right( 4 ) == _( ".GIF" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".ANI" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".IFF" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".TGA" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".PICT" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".ICON" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".TIFF" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".JPEG" ) ) {
    return( true );
  }
  if( fn.Right( 5 ) == _( ".JFIF" ) ) {
    return( true );
  }
  return( false );
}

int XPMEditor::OpenFile( const wxString& filename ) {
  if( !XPM_Plugin() ) {
    return( 1 );
  }
  if( XPM_Plugin()->OpenInEditor( filename ) ) {
    return( 0 );
  }
  return( 1 );
}

bool XPMEditor::HandlesEverything() const {
  return( false );
}

XPMEditor* XPMEditor::Get( void ) {
  return( m_Singleton );
}

void XPMEditor::OnAttach() {
  if( m_Singleton == NULL ) {
    wxInitAllImageHandlers();
    m_Singleton = this;
  }
}

void XPMEditor::OnRelease( bool appShutDown ) {
  if( !appShutDown ) {
    CloseMyEditors();
  }
}

bool XPMEditor::OpenInEditor( wxString FileName ) {
  if( Manager::Get()->GetEditorManager()->IsOpen( FileName ) ) {
    if( Manager::Get()->GetEditorManager()->GetEditor( FileName ) ) {
      Manager::Get()->GetEditorManager()->GetEditor( FileName )->Activate();
    }
    return( true );
  } else {
    XPMEditorBase *NewEditor;
    wxString title = wxFileName( FileName ).GetFullName();
    wxString fn;
    wxBitmapType bt;
    bool bRecognized;
    fn = FileName;
    fn.MakeUpper();
    bRecognized = false;
    if( fn.Right( 4 ) == _( ".XPM" ) ) {
      bt = wxBITMAP_TYPE_XPM;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".ICO" ) ) {
      bt = wxBITMAP_TYPE_ICO;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".CUR" ) ) {
      bt = wxBITMAP_TYPE_CUR;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".XBM" ) ) {
      bt = wxBITMAP_TYPE_XBM;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".BMP" ) ) {
      bt = wxBITMAP_TYPE_BMP;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".TIF" ) ) {
      bt = wxBITMAP_TYPE_TIF;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".JPG" ) ) {
      bt = wxBITMAP_TYPE_JPEG;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".JPE" ) ) {
      bt = wxBITMAP_TYPE_JPEG;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".DIB" ) ) {
      bt = wxBITMAP_TYPE_BMP;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".PNG" ) ) {
      bt = wxBITMAP_TYPE_PNG;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".PNM" ) ) {
      bt = wxBITMAP_TYPE_PNM;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".PCX" ) ) {
      bt = wxBITMAP_TYPE_PCX;
      bRecognized = true;
    }
    if( fn.Right( 4 ) == _( ".GIF" ) ) {
      bt = wxBITMAP_TYPE_GIF;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".ANI" ) ) {
      bt = wxBITMAP_TYPE_ANI;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".IFF" ) ) {
      bt = wxBITMAP_TYPE_IFF;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".TGA" ) ) {
      bt = wxBITMAP_TYPE_TGA;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".PICT" ) ) {
      bt = wxBITMAP_TYPE_PICT;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".ICON" ) ) {
      bt = wxBITMAP_TYPE_ICON;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".TIFF" ) ) {
      bt = wxBITMAP_TYPE_TIF;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".JPEG" ) ) {
      bt = wxBITMAP_TYPE_JPEG;
      bRecognized = true;
    }
    if( fn.Right( 5 ) == _( ".JFIF" ) ) {
      bt = wxBITMAP_TYPE_JPEG;
      bRecognized = true;
    }
    if( !bRecognized ) {
      bt = wxBITMAP_TYPE_ANY;
    }
    wxImage img;
    if( !( img.LoadFile( FileName, bt ) ) ) {
      return( false );
    }
    NewEditor = new XPMEditorBase( Manager::Get()->GetEditorManager()->GetNotebook(), title, &img, FileName );
    if( NewEditor ) {
      ProjectFile *pf;
      pf = FindProjectFile( FileName );
      if( pf ) {
        NewEditor->SetTitle( pf->relativeToCommonTopLevelPath );
        NewEditor->SetProjectFile( pf );
      }
      Manager::Get()->GetEditorManager()->SetActiveEditor( NewEditor );
    }
    return( true );
  }
  return( false );
}

void XPMEditor::CloseMyEditors( void ) {
  XPMEditorBase::CloseAllEditors();
}

ProjectFile* XPMEditor::FindProjectFile( const wxString& fileName ) {
  ProjectsArray* projects = ProjectManager::Get()->GetProjects();
  if( !projects ) {
    return( NULL );
  }
  for( size_t i = 0; i < projects->Count(); ++i ) {
    M_Code_Project* project = ( *projects )[i];
    if( !project ) {
      continue;
    }
    ProjectFile* file = project->GetFileByFilename( fileName, false, false );
    if( file ) {
      return( file );
    }
  }
  return( NULL );
}

bool XPMEditor::ReadConfiguration( bool bDefault ) {
  bool bSuccess;
  bSuccess = false;
  if( ( bDefault ) && ( !bSuccess ) ) {
    iMaxUndoRedo = XPM_MAX_UNDO;
    iXPMDefaultWidth = XPM_DEFAULT_WIDTH;
    iXPMDefaultHeight = XPM_DEFAULT_HEIGHT;
    iOpenXPM = 0;
    cBackgroundColour = *wxLIGHT_GREY;
    iNbColours = 68;
    DefaultColourArray = new wxColour[iNbColours];
    if( DefaultColourArray ) {
      DefaultColourArray[0] = wxTheColourDatabase->Find( _( "BLACK" ) );
      DefaultColourArray[1] = wxTheColourDatabase->Find( _( "BLUE VIOLET" ) );
      DefaultColourArray[2] = wxTheColourDatabase->Find( _( "MAGENTA" ) );
      DefaultColourArray[3] = wxTheColourDatabase->Find( _( "VIOLET" ) );
      DefaultColourArray[4] = wxTheColourDatabase->Find( _( "VIOLET RED" ) );
      DefaultColourArray[5] = wxTheColourDatabase->Find( _( "MEDIUM VIOLET RED" ) );
      DefaultColourArray[6] = wxTheColourDatabase->Find( _( "PINK" ) );
      DefaultColourArray[7] = wxTheColourDatabase->Find( _( "PLUM" ) );
      DefaultColourArray[8] = wxTheColourDatabase->Find( _( "PURPLE" ) );
      DefaultColourArray[9] = wxTheColourDatabase->Find( _( "SALMON" ) );
      DefaultColourArray[10] = wxTheColourDatabase->Find( _( "BLUE" ) );
      DefaultColourArray[11] = wxTheColourDatabase->Find( _( "AQUAMARINE" ) );
      DefaultColourArray[12] = wxTheColourDatabase->Find( _( "CADET BLUE" ) );
      DefaultColourArray[13] = wxTheColourDatabase->Find( _( "CORAL" ) );
      DefaultColourArray[14] = wxTheColourDatabase->Find( _( "CORNFLOWER BLUE" ) );
      DefaultColourArray[15] = wxTheColourDatabase->Find( _( "MEDIUM AQUAMARINE" ) );
      DefaultColourArray[16] = wxTheColourDatabase->Find( _( "MEDIUM BLUE" ) );
      DefaultColourArray[17] = wxTheColourDatabase->Find( _( "CYAN" ) );
      DefaultColourArray[18] = wxTheColourDatabase->Find( _( "DARK SLATE BLUE" ) );
      DefaultColourArray[19] = wxTheColourDatabase->Find( _( "DARK TURQUOISE" ) );
      DefaultColourArray[20] = wxTheColourDatabase->Find( _( "LIGHT BLUE" ) );
      DefaultColourArray[21] = wxTheColourDatabase->Find( _( "LIGHT STEEL BLUE" ) );
      DefaultColourArray[22] = wxTheColourDatabase->Find( _( "MEDIUM SLATE BLUE" ) );
      DefaultColourArray[23] = wxTheColourDatabase->Find( _( "MEDIUM TURQUOISE" ) );
      DefaultColourArray[24] = wxTheColourDatabase->Find( _( "MIDNIGHT BLUE" ) );
      DefaultColourArray[25] = wxTheColourDatabase->Find( _( "NAVY" ) );
      DefaultColourArray[26] = wxTheColourDatabase->Find( _( "SKY BLUE" ) );
      DefaultColourArray[27] = wxTheColourDatabase->Find( _( "SLATE BLUE" ) );
      DefaultColourArray[28] = wxTheColourDatabase->Find( _( "STEEL BLUE" ) );
      DefaultColourArray[29] = wxTheColourDatabase->Find( _( "TURQUOISE" ) );
      DefaultColourArray[30] = wxTheColourDatabase->Find( _( "KHAKI" ) );
      DefaultColourArray[31] = wxTheColourDatabase->Find( _( "DARK GREEN" ) );
      DefaultColourArray[32] = wxTheColourDatabase->Find( _( "DARK OLIVE GREEN" ) );
      DefaultColourArray[33] = wxTheColourDatabase->Find( _( "FOREST GREEN" ) );
      DefaultColourArray[34] = wxTheColourDatabase->Find( _( "MEDIUM FOREST GREEN" ) );
      DefaultColourArray[35] = wxTheColourDatabase->Find( _( "GREEN" ) );
      DefaultColourArray[36] = wxTheColourDatabase->Find( _( "GREEN YELLOW" ) );
      DefaultColourArray[37] = wxTheColourDatabase->Find( _( "LIME GREEN" ) );
      DefaultColourArray[38] = wxTheColourDatabase->Find( _( "MEDIUM SEA GREEN" ) );
      DefaultColourArray[39] = wxTheColourDatabase->Find( _( "MEDIUM SPRING GREEN" ) );
      DefaultColourArray[40] = wxTheColourDatabase->Find( _( "SPRING GREEN" ) );
      DefaultColourArray[41] = wxTheColourDatabase->Find( _( "PALE GREEN" ) );
      DefaultColourArray[42] = wxTheColourDatabase->Find( _( "SEA GREEN" ) );
      DefaultColourArray[43] = wxTheColourDatabase->Find( _( "YELLOW" ) );
      DefaultColourArray[44] = wxTheColourDatabase->Find( _( "YELLOW GREEN" ) );
      DefaultColourArray[45] = wxTheColourDatabase->Find( _( "GOLD" ) );
      DefaultColourArray[46] = wxTheColourDatabase->Find( _( "GOLDENROD" ) );
      DefaultColourArray[47] = wxTheColourDatabase->Find( _( "MEDIUM GOLDENROD" ) );
      DefaultColourArray[48] = wxTheColourDatabase->Find( _( "ORANGE" ) );
      DefaultColourArray[49] = wxTheColourDatabase->Find( _( "ORANGE RED" ) );
      DefaultColourArray[50] = wxTheColourDatabase->Find( _( "WHEAT" ) );
      DefaultColourArray[51] = wxTheColourDatabase->Find( _( "RED" ) );
      DefaultColourArray[52] = wxTheColourDatabase->Find( _( "ORCHID" ) );
      DefaultColourArray[53] = wxTheColourDatabase->Find( _( "DARK ORCHID" ) );
      DefaultColourArray[54] = wxTheColourDatabase->Find( _( "FIREBRICK" ) );
      DefaultColourArray[55] = wxTheColourDatabase->Find( _( "INDIAN RED" ) );
      DefaultColourArray[56] = wxTheColourDatabase->Find( _( "MEDIUM ORCHID" ) );
      DefaultColourArray[57] = wxTheColourDatabase->Find( _( "BROWN" ) );
      DefaultColourArray[58] = wxTheColourDatabase->Find( _( "MAROON" ) );
      DefaultColourArray[59] = wxTheColourDatabase->Find( _( "THISTLE" ) );
      DefaultColourArray[60] = wxTheColourDatabase->Find( _( "SIENNA" ) );
      DefaultColourArray[61] = wxTheColourDatabase->Find( _( "TAN" ) );
      DefaultColourArray[62] = wxTheColourDatabase->Find( _( "DARK GREY" ) );
      DefaultColourArray[63] = wxTheColourDatabase->Find( _( "DARK SLATE GREY" ) );
      DefaultColourArray[64] = wxTheColourDatabase->Find( _( "DIM GREY" ) );
      DefaultColourArray[65] = wxTheColourDatabase->Find( _( "GREY" ) );
      DefaultColourArray[66] = wxTheColourDatabase->Find( _( "LIGHT GREY" ) );
      DefaultColourArray[67] = wxTheColourDatabase->Find( _( "WHITE" ) );
      cTransparent = *wxLIGHT_GREY;
    }
  }
  return( bSuccess );
}

bool XPMEditor::WriteConfiguration( void ) {
  return( false );
}

void XPMEditor::SetMaxUndoRedo( int iMax ) {
  iMaxUndoRedo = iMax;
  UpdateConfiguration();
}

int XPMEditor::GetMaxUndoRedo( void ) {
  return( iMaxUndoRedo );
}

void XPMEditor::SetDefaultImageSize( int iWidth, int iHeight ) {
  iXPMDefaultWidth = iWidth;
  iXPMDefaultHeight = iHeight;
  if( iXPMDefaultWidth <= 0 ) {
    iXPMDefaultWidth = XPM_DEFAULT_WIDTH;
  }
  if( iXPMDefaultHeight <= 0 ) {
    iXPMDefaultHeight = XPM_DEFAULT_HEIGHT;
  }
  UpdateConfiguration();
}

void XPMEditor::GetDefaultImageSize( int *iWidth, int *iHeight ) {
  if( iWidth ) {
    *iWidth = iXPMDefaultWidth;
  }
  if( iHeight ) {
    *iHeight = iXPMDefaultHeight;
  }
}

bool XPMEditor::SetColourArray( wxColour *array, int inbColours, wxColour cTransparentColour ) {
  if( !array ) {
    return( false );
  }
  if( inbColours <= 0 ) {
    return( false );
  }
  wxColour *newArray;
  newArray = new wxColour[inbColours];
  if( !newArray ) {
    return( false );
  }
  int i;
  iNbColours = inbColours;
  for( i = 0; i < inbColours; i++ ) {
    newArray[i] = array[i];
  }
  delete[] DefaultColourArray;
  DefaultColourArray = newArray;
  cTransparent = cTransparentColour;
  return( true );
}

void XPMEditor::GetColourArray( wxColour *array, int *inbColours, wxColour *cTransparentColour ) {
  if( ( array ) && ( DefaultColourArray ) ) {
    int i;
    for( i = 0; i < iNbColours; i++ ) {
      array[i] = DefaultColourArray[i];
    }
  }
  if( inbColours ) {
    *inbColours = iNbColours;
  }
  if( cTransparentColour ) {
    *cTransparentColour = cTransparent;
  }
}

void XPMEditor::SetBackGroundColour( wxColour cBackColour ) {
  cBackgroundColour = cBackColour;
  UpdateConfiguration();
}

wxColour XPMEditor::GetBackGroundColour( void ) {
  return( cBackgroundColour );
}

void XPMEditor::UpdateConfiguration( void ) {
  int i, iMax;
  EditorBase *ed;
  if( !EditorManager::Get() ) {
    return;
  }
  iMax = EditorManager::Get()->GetEditorsCount();
  for( i = 0; i < iMax; i++ ) {
    ed = EditorManager::Get()->GetEditor( i );
    if( !ed ) {
      continue;
    }
    if( XPMEditorBase::IsImgEditor( ed ) ) {
      ( ( XPMEditorBase * )ed )->UpdateConfiguration();
    }
  }
}
